/*
 * TestPlanetaApp.cpp
 *
 *  Created on: 09/02/2010
 *      Author: San Martín, Matías I.
 */

#include <iostream>

#include "../../../Aplicacion/Modelo/EnPlaneta/Planeta.h"
#include "../../../Aplicacion/Common/Registry.h"
#include "../../../Aplicacion/Common/Mensajes/DatosMensajeFactory.h"
#include "MockDirectorio.h"
#include "MockMsjEmisor.h"
#include "MockMsjReceptor.h"

using namespace aplicacion::planeta;
using namespace std;

static InformacionPlaneta infoPlanetaAlt;

static void enviarInicio(MockMsjReceptor& recept,IdPlaneta& idP)
{
	MensajeAplicacion msj;
	DatosInicioJuego* datos = DatosMensajeFactorySingleton::instance().createInicioJuego();

	IdJuego juego(4);
	IdJugador j;
	datos->_idJuego = juego;
	msj.getEncabezado().setOrigen(j);
	msj.getEncabezado().setDestino(idP);
	msj.getEncabezado().setTipo(datos->getTipo());
	msj.setDatos(datos);

	//envio cambio de dueño
	recept.enviarMensaje(msj,idP);
}

static void enviarCambioDuenio(MockMsjReceptor& recept,IdPlaneta& idP)
{
	MensajeAplicacion msj;
	DatosCambiaDuenio* datos = DatosMensajeFactorySingleton::instance().createCambiaDuenio();

	IdJuego juego(4);
	datos->_duenioNuevo.setId(3);
	datos->_duenioNuevo.setContainerId(juego);
	msj.getEncabezado().setOrigen(datos->_duenioNuevo);
	msj.getEncabezado().setDestino(idP);
	msj.getEncabezado().setTipo(datos->getTipo());
	msj.setDatos(datos);

	//envio cambio de dueño
	recept.enviarMensaje(msj,idP);
}

static void enviarOrdenCrearFlota(MockMsjReceptor& recept,IdPlaneta& idP)
{
	MensajeAplicacion msj;
	DatosCrearFlotaOrden* datos = DatosMensajeFactorySingleton::instance().createCrearFlotaOrden();

	IdUniverso idUni(21);
	IdPlaneta	planetaDestino(20,idUni);

	IdJuego juego(4);
	IdJugador jugador(3,juego);

	datos->_idFlota = 10;
	datos->_proporcionNaves = 1.0;
	datos->_semilla = 0;
	datos->_planetaDestino = planetaDestino;

	msj.getEncabezado().setOrigen(jugador);
	msj.getEncabezado().setDestino(idP);
	msj.getEncabezado().setTipo(datos->getTipo());
	msj.setDatos(datos);

	//envio cambio de dueño
	recept.enviarMensaje(msj,idP);
}

static void verFlota()
{
	IdFlota id(1);
	IdJuego idJuego(1000);
	IdJugador idDuenio(50,idJuego);
	id.setIdJugador(idDuenio);

	Posicion dest(20,25);
	Flota flota(id, 100 /*cant naves*/, 9 /*semilla*/,
			infoPlanetaAlt._tamanio * Planeta::FACTOR_ESCALA_TAMANIO /*escala distr*/,
			infoPlanetaAlt._posicion, dest,
			0 /*tiempo*/);

	t_constPtrNaves* naves = flota.getNavesPorTiempoHastaCantidad(flota.getCantidadNaves());

	t_constPtrNaves::iterator fin = naves->end();
	for (t_constPtrNaves::iterator i = naves->begin(); i != fin; i++)
	{
		cout << *(*i) << " Tiempo arribo " << (*i)->getTiempoArribo(dest) << "\n";
	}

	delete naves;
}

static void enviarCreacionFlota(MockMsjReceptor& recept,IdPlaneta& idP,
								T_ID_FLOTA idFlota, size_t cantidadNaves)
{
	MensajeAplicacion msj;
	DatosCrearFlotaAvisoDestino* datos =
			DatosMensajeFactorySingleton::instance().createCrearFlotaAvisoDestino();

	datos->_idFlota.setId(idFlota);
	datos->_idFlota.setIdJugador(infoPlanetaAlt._duenio);
	datos->_cantidadNaves = cantidadNaves;
	datos->_semilla = 9;

	msj.getEncabezado().setOrigen(infoPlanetaAlt._identificador);
	msj.getEncabezado().setDestino(idP);
	msj.getEncabezado().setTipo(datos->getTipo());
	msj.setDatos(datos);

	//envio cambio de dueño
	recept.enviarMensaje(msj,idP);
}

static void enviarOrdenCambiarRumboFlota(MockMsjReceptor& recept,IdPlaneta& idP,
								T_ID_FLOTA idFlota)
{
	MensajeAplicacion msj;
	DatosCambiarRumboOrden* datos =
			DatosMensajeFactorySingleton::instance().createCambiarRumboOrden();

	datos->_idDestinoNuevo = infoPlanetaAlt._identificador;
	datos->_idFlota = idFlota;

	msj.getEncabezado().setOrigen(infoPlanetaAlt._duenio);
	msj.getEncabezado().setDestino(idP);
	msj.getEncabezado().setTipo(datos->getTipo());
	msj.setDatos(datos);

	//envio cambio de dueño
	recept.enviarMensaje(msj,idP);
}

static void enviarCambioRumboFlota(MockMsjReceptor& recept,IdPlaneta& idP,
								T_ID_FLOTA idFlota)
{
	IdFlota id(idFlota);
	IdJuego idJuego(4);
	IdJugador idDuenio(50,idJuego);
	id.setIdJugador(idDuenio);

	Posicion dest(40,25);
	Flota* flota = new Flota(id, 30 /*cant naves*/, 9 /*semilla*/,
			infoPlanetaAlt._tamanio * Planeta::FACTOR_ESCALA_TAMANIO /*escala distr*/,
			infoPlanetaAlt._posicion, dest,
			0 /*tiempo*/);

	MensajeAplicacion msj;
	DatosCambiarRumboAvisoDestino* datos =
			DatosMensajeFactorySingleton::instance().createCambiarRumboAvisoDestino(flota);

	datos->_idFlota = id;

	msj.getEncabezado().setOrigen(infoPlanetaAlt._duenio);
	msj.getEncabezado().setDestino(idP);
	msj.getEncabezado().setTipo(datos->getTipo());
	msj.setDatos(datos);

	//envio cambio de dueño
	recept.enviarMensaje(msj,idP);
}

//--------------------------------------------------------------------------

int main(int argc, char **argv) {

	bool esAplicacion = false;

	MockMsjReceptor recept(esAplicacion);

	IdUniverso idU(2);
	IdPlaneta idP(1,idU);

	IdJuego juego(4);
	IdJugador jugador(99,juego);
	IdUniverso idUni(21);
	infoPlanetaAlt._identificador.setId(20);
	infoPlanetaAlt._identificador.setContainerId(idUni);
	infoPlanetaAlt._duenio = jugador;
	infoPlanetaAlt._cantidadNaves = 10000;
	infoPlanetaAlt._tamanio = 11;
	infoPlanetaAlt._posicion.setXY(100,200);

//	verFlota();

	//Ejecuto el planeta
	if (esAplicacion)
	{
		cout << "Ejecucion planeta\n";
		MockMsjEmisor emisor;
		MockDirectorio dir;
		dir.addInformacionPlaneta(infoPlanetaAlt);
		RegistrySingleton::instance().setDirectorio(&dir);
		DatosMensajeFactorySingleton::instance().setContexto(DatosMensajeFactory::CONTEXTO_PLANETA);

		//Posicion pos(20,25);
		Posicion pos(10000,20000);

		//creo el planeta
		Planeta p(idP,100,pos);
		p.init(&recept,&emisor);

		//inicio ejecucion del planeta
		p.run();
	}

	//Ejecuto el envio de mensajes
	else {
		cout << "Ejecucion mensajes\n";
		//abro el pipe de salida
		recept.registrarPipe(Planeta::getFdName(idP),idP);

		enviarInicio(recept,idP);

		sleep(5);
		cout << "Envio cambio dueño\n";

		enviarCambioDuenio(recept,idP);

		while (true)
			sleep(2);

		enviarOrdenCrearFlota(recept,idP);

		sleep(2);

		enviarCreacionFlota(recept,idP,5,100);

		sleep(3);

		enviarCreacionFlota(recept,idP,6,50);

		enviarOrdenCambiarRumboFlota(recept,idP,6);

		sleep(2);

		enviarCambioRumboFlota(recept,idP,9);

		cout << "Ingresar caracter para terminar";
		char c;
		cin >> c;
	}
}

